home *** CD-ROM | disk | FTP | other *** search
/ CD Ware Multimedia 1995 May / cd Ware (Juegos) Epimundo.iso / DOS / C / RANDGEN.ZIP / RANDGEN.ASM < prev    next >
Encoding:
Assembly Source File  |  1988-07-23  |  3.7 KB  |  128 lines

  1. rt        equ    0dh
  2. lf        equ    0ah
  3. of        equ    offset
  4. sh        equ    short
  5.  
  6. code        segment
  7.         assume    cs:code, ds:code
  8.         org    100h
  9.  
  10. begin:        jmp    start
  11.  
  12. ; Note:  24 and 55 are not arbitrary.  They have been chosen so that the least
  13. ; significant bits in the sequence of pseudorandom integers have a period of
  14. ; length 2^55 - 1.  The sequence of pseudorandom numbers themselves have period
  15. ; 2^f*(2^55 - 1) where 0 <= f <= 16.  See Knuth's Volume 2 "Seminumerical
  16. ; Algorithms" of the second edition of the three volume set THE ART OF COMPUTER
  17. ; PROGRAMMING (pages 26 & 27).
  18.  
  19. j        dw    24 * 2        ; multiply by 2 for word offsets
  20. k        dw    55 * 2
  21.  
  22. ; Array of 55 seed elements for the additive pseudorandom number generator.
  23.  
  24. add_array    dw    ?    ; this location (offset 0 word) is not used
  25.         dw    7952,    42720,    56941,    47825,    52353,    4829,    32133
  26.         dw    29787,    7028,    62292,    46128,    34856,    63646,    21032
  27.         dw    62660,    61244,    35057,    36989,    43989,    46043,    48547
  28.         dw    43704,    29749,    21898,    10279,    48252,    35578,    27916
  29.         dw    3633,    50349,    33655,    36965,    48566,    43375,    15168
  30.         dw    30425,    8425,    31783,    3625,    23789,    37438,    64887
  31.         dw    19015,    43108,    61545,    24901,    58349,    52290,    62047
  32.         dw    21173,    27055,    27851,    47955,    14377,    14434
  33.  
  34. randomize    proc    near        ; randomize the random number generator
  35.         push    ax        ; save
  36.         push    bx
  37.         mov    ax,40h        ; set ds to BIOS data area
  38.         mov    ds,ax
  39.         mov    bx,6ch        ; location of low word of 4-byte count
  40.         mov    ax,[bx]        ; get low word of 4-byte clock count
  41.         push    cs        ; reset ds for code addressing
  42.         pop    ds
  43.         mov    bx,of add_array    ; address array of seed elements
  44.         add    bx,2        ; offset 0 is not used
  45.         mov    cx,55        ; shall adjust all 55 seeds
  46. set_seed:    add    [bx],ax        ; randomize seed value with current time
  47.         add    bx,2        ; move to next one
  48.         loop    set_seed
  49.         pop    bx
  50.         pop    ax
  51.         ret
  52. randomize    endp
  53.  
  54. random        proc    near        ; generate pseudorandom number in ax
  55.         push    bx        ; save
  56.         push    cx
  57.         mov    bx,j        ; get j index
  58.         mov    cx,add_array[bx]; and load array element into cx
  59.         mov    bx,k        ; get k index
  60.         mov    ax,add_array[bx]; and load array element into ax
  61.         add    ax,cx        ; new element and return value to ax
  62.         mov    add_array[bx],ax; store new element at location k
  63.         sub    j,2        ; move down one element
  64.         sub    k,2        ; move down one element
  65.         cmp    j,0        ; is j down to 0?
  66.         jne    check_k        ; no, check k
  67.         mov    j,55 * 2    ; set i to end of array
  68. check_k:    cmp    k,0        ; is k down to 0?
  69.         jne    random_out    ; no, leave
  70.         mov    k,55 * 2    ; set k to end of array
  71. random_out:    pop    cx        ; restore
  72.         pop    bx
  73.         ret
  74. random        endp
  75.  
  76. number        db    5 dup(?)    ; reserve memory for output number
  77. new_line    db    rt,lf,'$'    ; new line and DOS terminator
  78. initial        db    '    0'        ; initialization value for number
  79.  
  80. write_dec_ax    proc    near        ; write decimal of ax to standard out
  81.         push    ax        ; save
  82.         push    bx
  83.         push    cx
  84.         push    dx
  85.         push    si
  86.         push    di
  87.         pushf            ; save direction flag
  88.         mov    si,of initial    ; initialize output area
  89.         mov    di,of number
  90.         mov    cx,5
  91.         cld
  92.         rep    movsb
  93.         mov    bx,10        ; base 10 divisor
  94.         mov    di,of new_line-1; point to last digit position
  95.         std            ; backward now
  96. next_digit:    or    ax,ax        ; are we through?
  97.         je    wda_out        ; yes, output result
  98.         xor    dx,dx        ; clear high order end
  99.         div    bx        ; next digit in result to dl
  100.         xchg    ax,dx        ; place digit in al
  101.         add    al,30h        ; convert to ascii digit
  102.         stosb            ; store it in output area
  103.         xchg    ax,dx        ; quotient back to ax
  104.         jmp    sh next_digit    ; loop
  105. wda_out:    mov    ah,9        ; let DOS output the number
  106.         mov    dx,of number
  107.         int    21h
  108.         popf            ; restore
  109.         pop    di
  110.         pop    si
  111.         pop    dx
  112.         pop    cx
  113.         pop    bx
  114.         pop    ax
  115.         ret
  116. write_dec_ax    endp
  117.         
  118. start:        call    randomize    ; randomize the generator
  119.         mov    cx,250        ; number of randoms to write
  120. next:        call    random        ; get a random number to ax
  121.         call    write_dec_ax    ; write decimal of ax to con
  122.         loop    next
  123.  
  124.         int    20h        ; end
  125.  
  126. code        ends
  127.         end    begin
  128.